/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.unicode.unihan.parser;

import org.geergenbein.parser.DocumentParser;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import org.unicode.unihan.domain.UnihanInfo;
import org.unicode.unihan.domain.UnihanRow;

/**
 *
 * @author Andrew
 */
public class UnihanInfoParser implements Iterable<UnihanInfo>,
        Iterator<UnihanInfo> {

    private DocumentParser<UnihanRow> unihanParser;
    private UnihanRow nextRow = null;
    private UnihanInfo nextInfo = null;

    public UnihanInfoParser(InputStream is) {
        unihanParser = new DocumentParser(is, new UnihanLineParser());
    }

    public UnihanInfoParser(String path) throws FileNotFoundException {
        unihanParser = new DocumentParser(path, new UnihanLineParser());
    }

    public Iterator<UnihanInfo> iterator() {
        return this;
    }

    public boolean hasNext() {
        if (nextInfo == null) {
            parseNextUnihanInfo();
        }
        return nextInfo != null;
    }

    public UnihanInfo next() {
        if (nextInfo == null) {
            parseNextUnihanInfo();
        }
        UnihanInfo temp = nextInfo;
        nextInfo = null;
        return temp;
    }

    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }

    public String toString(UnihanInfo unihanInfo) {
        StringBuilder sb = new StringBuilder();
        UnihanLineParser parser = new UnihanLineParser();
        // TODO: use true join functino
        for (Map.Entry<String, String> entry : unihanInfo.getProperties()) {
            UnihanRow unihanRow = new UnihanRow(unihanInfo.getUnicode(),
                    entry.getKey(), entry.getValue());
            sb.append(parser.toString(unihanRow) + "\n");
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    public String toString(UnihanRow... unihanRows) {
        StringBuilder sb = new StringBuilder();
        // TODO: use a true join function here
        for (UnihanRow unihanRow : unihanRows) {
            sb.append(unihanRow.toString() + "\n");
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

    private void parseNextUnihanInfo() {
        if (nextRow == null) {
            nextInfo = null;
        } else {
            // TODO: should we add a construct to pass in a
            nextInfo = new UnihanInfo(nextRow.getUnicode());
            nextInfo.addProperty(nextRow.getKey(), nextRow.getValue());
        }
        // TODO: we need to make sure that the unicode value is not null
        while ((nextInfo == null ||
                nextInfo.getUnicode().equals(nextRow.getUnicode())) &&
                unihanParser.hasNext())
        {
            nextRow = unihanParser.next();
            if (nextInfo == null) {
                nextInfo = new UnihanInfo(nextRow.getUnicode());
            }
            if (nextInfo.getUnicode().equals(nextRow.getUnicode())) {
                nextInfo.addProperty(nextRow.getKey(), nextRow.getValue());
            }
        }

        if (! unihanParser.hasNext()) {
            nextRow = null;
        }
    }
    
}
